/***************************************************************************************
 The copyright in this software is being made available under the BSD License, included
 below. This software may be subject to other third party rights,including patent rights,
 and no such rights are granted under this license.

 Regents of the Tsinghua University, Peking University, Zhejiang University, HKUST
 Tsinghua University, Peking University, Zhejiang University, HKUST 2011

 Copyright (c) 2011, Regents of the Tsinghua University, Peking University, Zhejiang
 University, HKUST. All Rights Reserved.

 Redistribution and use in source and binary forms, with or without modification, are
 permitted provided that the following conditions are met:
   * Redistributions of source code must retain the above copyright notice,
     this list of conditions and the following disclaimer.
   * Redistributions in binary form must reproduce the above copyright notice,
     this list of conditions and the following disclaimer in the documentation
     and/or other materials provided with the distribution.
   * Neither the names of the copyright holders nor the names of its
     contributors may be used to endorse or promote products derived from this
     software without specific prior written permission.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
 OF SUCH DAMAGE.
***************************************************************************************/


#ifndef _DEFINES_H_
#define _DEFINES_H_

#if defined(WIN32) && !defined(__MINGW32__)
#pragma warning(disable: 4996)
#pragma warning(disable: 4244)
# define  snprintf _snprintf
# define  open     _open
# define  close    _close
# define  read     _read
# define  write    _write
# define  lseek    _lseeki64
# define  fsync    _commit
# define  tell     _telli64
# define  ftime     _ftime
# define  TIMEB    _timeb
# define  TIME_T    LARGE_INTEGER
# define  OPENFLAGS_WRITE _O_WRONLY|_O_CREAT|_O_BINARY|_O_TRUNC
# define  OPEN_PERMISSIONS _S_IREAD | _S_IWRITE
# define  OPENFLAGS_READ  _O_RDONLY|_O_BINARY
# define  inline   _inline
# define  forceinline __forceinline
#else
# include <unistd.h>
# include <sys/time.h>

# include <time.h>
# include <stdint.h>
#if defined(OPENMP)
# include <omp.h>
#endif

# define  TIMEB    timeb
# define  TIME_T   struct timeval
# define  tell(fd) lseek(fd, 0, SEEK_CUR)
# define  OPENFLAGS_WRITE O_WRONLY|O_CREAT|O_TRUNC
# define  OPENFLAGS_READ  O_RDONLY
# define  OPEN_PERMISSIONS S_IRUSR | S_IWUSR
#if !defined(__CYGWIN__) && !defined(__MINGW32__)
# define  O_BINARY       0x8000
#endif
# if __STDC_VERSION__ >= 199901L
/* "inline" is a keyword */
# else
#  define inline /* nothing */
# endif
# define  forceinline inline

#define min(a,b) (((a) < (b)) ? (a) : (b))

#define max(a,b) (((a) > (b)) ? (a) : (b))

#endif


#define VERSION   "1.2 (2012-08-28)"
#define FastME

#define TRACE         0

#define RFM_MIN(a,b)            (((a)<(b)) ? (a) : (b))
#define RFM_MAX(a,b)            (((a)<(b)) ? (b) : (a))
#define RFM_ABS(a)              ((a)<(0)   ? (-(a)):(a))
#define RFM_CLIP1(a)            ((a)>255 ? 255 : ((a)<0  ?  0:(a)))
#define RFM_CLIP3(a,b,c)        ((a)<(b) ? (b) : ((a)>(c)?(c):(a)) )
#define MEDIAN(a,b,c)           (a + b + c - RFM_MIN(a, RFM_MIN(b, c)) - RFM_MAX(a, RFM_MAX(b, c)));
#define INTERPOLATE(a, b, c, d) RFM_CLIP1((-0*a + 4 * b + 4 * c - 0*d +4)/8)
//#define INTERPOLATE(a, b, c, d) RFM_CLIP1((-a + 5 * b + 5 * c - d +4)/8)

#define ET_SIZE                   300
#define RFM_MAX_VALUE          999999
#define LOG2_MAX_FRAME_NUM_MINUS4   4
#define _LUMA_COEFF_COST_           4
#define IMG_PAD_SIZE               16
#define B8_SIZE                     8
#define B4_SIZE                     4
#define TOTRUN_NUM                 15
#define MIN_QP                      0
#define MAX_QP                     63
#define SHIFT_QP                   11

#define INTRA_MODE_ADAPTIVE         1	//luma enable:1  disable:0
#define INTRA_MODE_ADAPTIVE_CHROMA  1	//chroma
#define INTRA_LEFT                  0
#define INTRA_UP                    1
#define INTRA_NO                    2
#define UV                          2
#define UV_MODE              INTER8x8
#define HALF_POS_NUM                3
#define P_A                         0
#define P_B                         1
#define P_C                         2
#define SKIP_REF_INDEX              0
#define MAX_REF_NUM                 2
#define MAX_REF_NUM_PLUS_1          (MAX_REF_NUM + 1)
#define NUM_PIC_TYPE                5
#define MAX_V_SEARCH_RANGE       1024
#define MAX_H_SEARCH_RANGE       8192
#define MAX_ITEMS_TO_PARSE       1000
#define STREAM_BUF_SIZE          1024
#define MAX_HEADER_SIZE           100
#define MAX_VALUE              (1<<30)

#define LAMBDA_ACCURACY_BITS         16
#define LAMBDA_FACTOR(lambda)        ((int)((double)(1<<LAMBDA_ACCURACY_BITS)*lambda+0.5))
#define WEIGHTED_COST(factor,bits)   (((factor)*(bits))>>LAMBDA_ACCURACY_BITS)
#define MV_COST(f,s,cx,cy,px,py)     (WEIGHTED_COST(f,mvbits[((cx)<<(s))-(px<<(s))]+mvbits[((cy)<<(s))-(py<<(s))]))

#define IS_INTRA(MB)    ((MB)->mb_type==I8MB)
#define IS_INTER(MB)    ((MB)->mb_type!=I8MB)
#define IS_INTERMV(MB)  ((MB)->mb_type!=I8MB && (MB)->mb_type != SKIP)
#define IS_COPY(MB)     ((MB)->mb_type== 0   && img ->type==P_IMG)
#define IS_P8x8(MB)     ((MB)->mb_type==INTER8x8)

#define B4_SIZE          4
#define B8_SIZE          8
#define MB_BLOCK_SIZE   16


#define QUARTER_PIXEL           1
#define QUARTER_wangIF          1

#define QUARTER_2D            0

#define RDO_Q
#define DEBLOCK                 0

#define RDO_STAT                0

#define SYNTAX_STAT             0

#if QUARTER_PIXEL
#define ROUNDING(x)             ((x > 0 ? x+1 : x-1)/4)
#define INTERPOLATE_QUATER1(a, b, c, d) RFM_CLIP1((-0*a + 3 * b + 1 * c - 0*d + 2)/4)  //dw 20110808
#define INTERPOLATE_QUATER2(a, b, c, d) RFM_CLIP1((-0*a + 1 * b + 3 * c - 0*d + 2)/4)  //dw 20110808

#define QUATER_POS_NUM              12  //dw 20110808
#define P_A1                        3  //dw 20110808
#define P_A2                        4  //dw 20110808
#define P_B1                        5  //dw 20110808
#define P_B2                        6  //dw 20110808
#define P_C1                        7  //dw 20110808
#define P_C2                        8  //dw 20110808
#define P_C3                        9  //dw 20110808
#define P_C4                        10  //dw 20110808
#define P_D1                        11  //dw 20110808
#define P_D2                        12  //dw 20110808
#define P_D3                        13  //dw 20110808
#define P_D4                        14  //dw 20110808
#endif

#define OPT_HP
#ifdef OPT_HP
#define HPGOPSIZE             4
#endif

#if QUARTER_wangIF

#define INTERPOLATE_8tap_HALF(a, b, c, d, e, f, g, h) RFM_CLIP1((-1*a + 4 * b - 11 * c + 40*d + 40*e - 11 * f + 4 * g -1*h + 32)/64)
#define INTERPOLATE_8tap_QUATER1(a, b, c, d, e, f, g, h) RFM_CLIP1((-1*a + 4 * b - 10 * c + 57*d + 18*e - 6 * f + 3 * g -1*h + 32)/64)
#define INTERPOLATE_8tap_QUATER3(a, b, c, d, e, f, g, h) RFM_CLIP1((-1*a + 3 * b -  6 * c + 18*d + 57*e -10 * f + 4 * g -1*h + 32)/64)

#define INTERPOLATE_6tap_HALF(a, b, c, d, e, f, g, h) RFM_CLIP1((-0*a + 2 * b - 9 * c + 39*d + 39*e - 9 * f + 2 * g -0*h + 32)/64)
#define INTERPOLATE_6tap_QUATER1(a, b, c, d, e, f, g, h) RFM_CLIP1((-0*a + 2 * b - 9 * c + 57*d + 17*e - 4 * f + 1 * g -0*h + 32)/64)
#define INTERPOLATE_6tap_QUATER3(a, b, c, d, e, f, g, h) RFM_CLIP1((-0*a + 1 * b - 4 * c + 17*d + 57*e - 9 * f + 2 * g -0*h + 32)/64)

#endif
#define INTERPOLATE2D(cof, a, b, c, d, e, f)      RFM_CLIP1((cof[0]*a + cof[1]*b + cof[2]*c + cof[3]*d + cof[4]*e + cof[5]*f + 128)/256)
#define INTERPOLATE2D_REV(cof, a, b, c, d, e, f)  RFM_CLIP1((cof[5]*a + cof[4]*b + cof[3]*c + cof[2]*d + cof[1]*e + cof[0]*f + 128)/256)

#define INTERPOLATE2D_NA(cof, a, b, c, d, e, f)      RFM_CLIP1((cof[0]*a + cof[1]*b + cof[2]*c + cof[3]*d + cof[4]*e + cof[5]*f)/256)
#define INTERPOLATE2D_NA_REV(cof, a, b, c, d, e, f)  RFM_CLIP1((cof[5]*a + cof[4]*b + cof[3]*c + cof[2]*d + cof[1]*e + cof[0]*f)/256)
#endif
